﻿using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;

namespace Xwltz.Framework.Helper
{
    public class ImageHepler
    {
        private readonly string _base64;
        private byte[] _imageBytes;

        public static string FileName { get; private set; }

        public ImageHepler(string base64)
        {
            _base64 = base64;
        }

        public ImageHepler Build()
        {
            var base64 = _base64.Substring(5);
            FileName = base64.Substring(0, base64.IndexOf(";base64", StringComparison.Ordinal));
            base64 = base64.Substring(base64.IndexOf(",", StringComparison.Ordinal) + 1).Replace(" ", "+");
            _imageBytes = Convert.FromBase64String(base64);
            return this;
        }

        public MemoryStream GetStream()
        {
            var ms = new MemoryStream(_imageBytes, 0, _imageBytes.Length);
            ms.Write(_imageBytes, 0, _imageBytes.Length);
            return ms;
        }

        public static void SaveToFileInQuality(Image image, string path, ImageFormat format)
        {
            var parameters = new EncoderParameters();
            parameters.Param[0] = new EncoderParameter(Encoder.Quality, new long[] { 90 });
            var encoder = ImageCodecInfo.GetImageEncoders().First(x => x.FormatID == format.Guid);
            image.Save(path, encoder, parameters);
        }

        public static Image CropCenter(Image image, int width)
        {
            var newSize = image.Size.Height > image.Size.Width ? new Size(width, width * image.Size.Height / image.Size.Width) : new Size(width * image.Size.Width / image.Size.Height, width);
            var bitmap = new Bitmap(width, width);

            var g = Graphics.FromImage(bitmap);
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
            g.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighQuality;

            g.DrawImage(image, (width - newSize.Width) / 2, (width - newSize.Height) / 2, newSize.Width, newSize.Height);
            g.Dispose();
            return bitmap;
        }

        public static Size ResizeTo(Size origin, Size target)
        {
            if (target.Width == 0 && target.Height == 0)
            {
                return origin;
            }
            if (target.Width == 0)
            {
                var rate = (float)origin.Height / target.Height;
                return rate <= 1 ? new Size(origin.Width, origin.Height) : new Size((int)(origin.Width / rate), target.Height);
            }

            if (target.Height == 0)
            {
                var rate = (float)origin.Width / target.Width;
                return rate <= 1 ? new Size(origin.Width, origin.Height) : new Size(target.Width, (int)(origin.Height / rate));
            }

            var size = new Size();
            var r = Math.Max(((float)origin.Width / target.Width), ((float)origin.Height) / target.Height);
            if (r <= 1)
            {
                return new Size(origin.Width, origin.Height);
            }
            size.Width = (int)Math.Round(origin.Width / r);
            size.Height = (int)Math.Round(origin.Height / r);
            if (size.Width == 0)
            {
                size.Width = 1;
            }
            if (size.Height == 0)
            {
                size.Height = 1;
            }
            return size;
        }

        public static ImageFormat GetImageFormat(string extension)
        {
            switch (extension.ToLower())
            {
                case ".png":
                    return ImageFormat.Png;
                case ".gif":
                    return ImageFormat.Gif;
                case ".ico":
                    return ImageFormat.Icon;
                case ".bmp":
                    return ImageFormat.Bmp;
            }
            return ImageFormat.Jpeg;
        }

        public static string GetExtension(ImageFormat format)
        {
            if (Equals(format, ImageFormat.Png))
            {
                return ".png";
            }
            if (Equals(format, ImageFormat.Bmp))
            {
                return ".bmp";
            }
            if (Equals(format, ImageFormat.Gif))
            {
                return ".gif";
            }
            return ".jpeg";
        }
    }
}
